﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication3    //命名空间
{
    public class Pcomm
    {
        /// <summary>
        /// 波特率
        /// </summary>
        public enum BaudRate   //接口所使用的波特率枚举
        {
            B50     = 0X00,
            B75     = 0X01,
            B110    = 0X02,
            B134    = 0X03,
            B150    = 0X04,
            B300    = 0X05,
            B600    = 0X06,
            B1200   = 0X07,
            B1800   = 0X08,
            B2400   = 0X09,
            B4800   = 0X0A,
            B7200   = 0X0B,
            B9600   = 0X0C,
            B19200  = 0X0D,
            B38400  = 0X0E,
            B57600  = 0X0F,
            B115200 = 0X10,
            B230400 = 0X11,
            B460800 = 0X12,
            B921600 = 0X13,
        }

        /// <summary>
        /// 数据位
        /// </summary>
        public enum DataBit    //接口所使用的数据位枚举
        {
            BIT_5 = 0X00,
            BIT_6 = 0X01,
            BIT_7 = 0X02,
            BIT_8 = 0X03,
        }

        /// <summary>
        /// 停止位
        /// </summary>
        public enum StopBit   //接口所使用的停止位枚举
        {
            STOP_1 = 0X00,
            STOP_2 = 0X04,
        }

        /// <summary>
        /// 校验位
        /// </summary>
        public enum Parity    //接口所使用的校验位枚举
        {
            P_EVEN = 0X18,
            P_ODD  = 0X08,
            P_SPC  = 0X38,
            P_MRK  = 0X28,
            P_NONE = 0X00,
        }

        /// <summary>
        /// 错误代码   
        /// </summary>
        public enum Error_Code        //错误代码枚举
        {
            SIO_OK = 0,               //正确
            SIO_BADPORT = -1,         //没有此端口或端口未打开 No such port or port not opened 
            SIO_OUTCONTROL = -2,      //无法控制此板 Can't control board
            SIO_NODATA = -4,          //没有数据供读取或没有缓冲区供写入 No data to read or no buffer to write
            SIO_OPENFAIL = -5,        //没有此端口或端口已打开 No such port or port has opened 
            SIO_RTS_BY_HW = -6,       //因为H/W流量控制而不能设置RTS Can't set because H/W flowctrl
            SIO_BADPARM = -7,         //无效参数 Bad parameter 
            SIO_WIN32FAIL = -8,       //调用WIN32函数失败请调用GetLastError函数以获取错误代码 Call win32 function fail, please call GetLastError to get the error code *)
            SIO_BOARDNOTSUPPORT = -9, //此版不支持这个函数 Board does not support this function
            SIO_FAIL = -10,           //PCOMM函数执运行结果失败 PComm function run result fail
            SIO_ABORT_WRITE = -11,    //写入已被锁定，用户也放弃写入 Write has blocked, and user abort write
            SIO_WRITETIMEOUT = -12,   //已发生写入超时 Write timeout has happened
        }

        #region 解析错误编码对应的错误信息
        /// <summary>
        /// 错误码对应的信息,接口返回错误代码解析
        /// </summary>
        /// <param name="errcode"></param>
        /// <returns></returns>
        public static string IoErrorMsg(int errcode)
        {
            switch (errcode)
            {
                case (int)Pcomm.Error_Code.SIO_OK:
                    return "正确";
                case (int)Pcomm.Error_Code.SIO_BADPORT:
                    return "没有此端口或端口未打开";
                case (int)Pcomm.Error_Code.SIO_OUTCONTROL:
                    return "无法控制此板";
                case (int)Pcomm.Error_Code.SIO_NODATA:
                    return "没有数据供读取或没有缓冲区供写入";
                case (int)Pcomm.Error_Code.SIO_OPENFAIL:
                    return "没有此端口或端口已打开";
                case (int)Pcomm.Error_Code.SIO_RTS_BY_HW:
                    return "因为H/W流量控制而不能设置";
                case (int)Pcomm.Error_Code.SIO_BADPARM:
                    return "无效参数";
                case (int)Pcomm.Error_Code.SIO_WIN32FAIL:
                    return "调用WIN32函数失败请调用GetLastError函数以获取错误代码";
                case (int)Pcomm.Error_Code.SIO_BOARDNOTSUPPORT:
                    return "此版不支持这个函数";
                case (int)Pcomm.Error_Code.SIO_FAIL:
                    return "PCOMM函数执运行结果失败";
                case (int)Pcomm.Error_Code.SIO_ABORT_WRITE:
                    return "写入已被锁定，用户也放弃写入";
                case (int)Pcomm.Error_Code.SIO_WRITETIMEOUT:
                    return "已发生写入超时";
            }

            return "未知错误";
        }
        #endregion 

        /// <summary>
        /// 中继触发事件回调函数委托定义
        /// </summary>
        public delegate void CallBackIrqProc(int port);   //定义委托类型

        /// <summary>
        /// 文件传送回调函数委托定义 !!!!!
        /// </summary>
        public delegate int CallBackFileProc(int len, int rlen, byte[] buf, int flen);  //定义委托类型

        #region 打开通讯端口
        /// <summary>
        /// 打开通讯端口！
        /// </summary>
        /// <param name="port">通讯端口号码</param>
        /// <returns></returns>
        [DllImport("PComm.dll", EntryPoint = "sio_open", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        unsafe public static extern int sio_open(int port);
        #endregion

        #region  关闭通讯端口
        /// <summary>
        /// 关闭通讯端口！
        /// </summary>
        /// <param name="port">通讯端口号码</param>
        /// <returns></returns>
        [DllImport("PComm.dll", EntryPoint = "sio_close", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        unsafe public static extern int sio_close(int port);
        #endregion

        #region 设置传输参数
        /// <summary>
        /// 设置传输的参数！
        /// </summary>
        /// <param name="port">通讯端口号码</param>
        /// <param name="baud">波特率</param>
        /// <param name="mode">校验位||数据位||停止位</param>
        /// <returns></returns>
        [DllImport("PComm.dll", EntryPoint = "sio_ioctl", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        unsafe public static extern int sio_ioctl(int port, int baud, int mode);
        #endregion

        #region 读取通讯端口数据
        /// <summary>
        /// 读取通讯端口数据,数据返回存放在buf, 读取len的长度
        /// </summary>
        /// <param name="port">通讯端口号码</param>
        /// <param name="buf">字节数组,用以存放接收到的字节数据</param>
        /// <param name="len">每一次所读取的数据长度（字节数）</param>
        /// <returns></returns>
        [DllImport("PComm.dll", EntryPoint = "sio_read", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        unsafe public static extern int sio_read(int port, byte[] buf, int len);
        #endregion

        #region 端口输出数据
        /// <summary>
        /// 输出数据！！往串口写数据
        /// </summary>
        /// <param name="port">通讯端口号码</param>
        /// <param name="buf">输出字符串的地址</param>
        /// <param name="len">输出字符串的长度</param>
        /// <returns></returns>
        [DllImport("PComm.dll", EntryPoint = "sio_write", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        unsafe public static extern int sio_write(int port, byte[] buf, int len);
        #endregion

        #region 接收到固定字符触发事件
        /// <summary>
        /// 接收到固定字符触发事件(设置中断),串口接收到1个字符,触发  irqproc 事件处理字符
        /// </summary>
        /// <param name="port">通讯端口号码</param>
        /// <param name="datareceived">函数地址</param>
        /// <param name="count">字符数(使用手册特别说明必须将字符数设置为1，也就是一有字符进来就触发事件)</param>
        /// <returns></returns>
        [DllImport("PComm.dll", EntryPoint = "sio_cnt_irq", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        unsafe public static extern int sio_cnt_irq(int port, CallBackIrqProc irqproc, int count);
        #endregion

        
    }
}
